/*
 * File Name : ls.cpp
 * Auther : dream.liuguobiao
 * Create Date : 2010-5-14
 * Last Edit : 2010-5-16
 */
#include <iostream>
#include <string>
#include <bitset>
#include <iomanip>

#include "ls.h"
#include "cd.h"
#include "my_string.h"

ls::ls( std::string *new_parameters)
:command(new_parameters)
{
//  type.set(1,0);
//  type.set(2,0);
//  type.set(3,0);
}

int ls::run_command(){
  my_string *MyString = my_string::get_my_string();
  std::string *sub_string = MyString->get_sub_string( *get_parameters() );
  node *current_directory = get_shell_environment()->get_file_system()->get_current_directory();
  if( '-' != *(sub_string->begin() )){
  command *my_cd = new cd(sub_string);
  my_cd->run_command(); 
  *sub_string = *get_parameters();
  }else if( '-' == *(sub_string->begin()) ){
    if( "--help" == *sub_string ){
      std::cout<<"Usage: ls [OPTION]... [FILE]...\n\nMandatory arguments to long options are mandatory for short options too.\n  -a, --all                  do not ignore entries starting with .\n  -l                         use a long listing format\n      --version  output version information and exit\n\nReport bugs to <bug-coreutils@gnu.org>.\n";
      return 0;
    }else if( "--version" == *sub_string ){
      std::cout<<"ls (GNU coreutils) 6.12\nCopyright (C) 2008 Free Software Foundation, Inc.\nLicense GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permitted by law.\n\nWritten by Richard Stallman and David MacKenzie.\n";
      return 0;
    }else if ( "-a" == *sub_string ){
      type.set(1);
    }else if ( "-l" == *sub_string ){
      type.set(2);
    }else {
      std::cout<<"ls: invalid option -- "<<*(sub_string->begin()+1)<<std::endl<<"Try `ls --help' for more information.\n";
      return 0;
    }
  }

  node *tmp_node ;
  tmp_node = get_shell_environment()->get_file_system()->get_current_directory()->get_son();
  while( NULL != tmp_node ){
    if( 1 == type[2] ){
      users *my_users = get_shell_environment()->get_all_users();
      groups *my_groups = get_shell_environment()->get_all_groups();
      std::string tmp_string;
      int UID = tmp_node->get_userID();
      int GID = tmp_node->get_groupID();
      if( 0 == tmp_node->get_type())tmp_string += 'd';
      else if( 1 == tmp_node->get_type())tmp_string += '-';
      else tmp_string += '-';
      tmp_string += "rwxrwxrwx";
// get the mod
      int mod = tmp_node->get_mod();
      int bit = 256;
      for(int i =1; i<10 ;i++){
        if(!(mod&bit))tmp_string[i] = '-'; 
        bit /= 2;
      }
      user *own_user = get_shell_environment()->get_administrator();
      if( UID != own_user->get_ID() ) 
        own_user = my_users->find_user_by_ID( UID );
      if ( NULL == own_user )
        {std::cout<<"\nNULL == own_user in ls.cpp\n";return 1;}

      group *own_group = my_groups->find_group_by_ID( GID );
      if ( NULL == own_group )
        {std::cout<<"\nNULL == own_group in ls.cpp\n";return 1;}

      std::cout<<std::setw(11)<<tmp_string<<std::setw(7)<<*(own_user->get_name() )<<std::setw(7)<<*(own_group->get_name() )<<std::setw(7)<<tmp_node->get_size()<<" kb"<<std::setw(12)<<*(tmp_node->get_name() );
      std::cout<<std::endl;
    }else{
      std::cout<<*(tmp_node->get_name())<<"   ";
    }
    tmp_node = tmp_node->get_brother();
  }
  get_shell_environment()->get_file_system()->set_current_directory(current_directory);
  std::cout<<std::endl;
  return 0;
}
